package com.wang.tool.monitor.writer;

import com.wang.tool.monitor.LinkLogUtil;
import com.wang.tool.monitor.aop.MonitorAdvice;
import com.wang.tool.monitor.core.LinkInfo;
import com.wang.tool.monitor.core.MonitorInfo;

import java.util.HashMap;
import java.util.Map;

/**
 * 记录监控信息
 *
 * @Author wangshaopeng
 * @Date 2022/5/10
 * @see MonitorAdvice#monitorAround
 */
public class SimpleMonitorWriter implements MonitorWriter {

    public static MonitorWriter getInstance() {
        return Single.SINGLE;
    }

    /**
     * 输出监控
     *
     * @param monitorInfo 非空
     */
    public static void simpleWrite(MonitorInfo<?> monitorInfo) {
        Single.SINGLE.write(monitorInfo);
    }

    @Override
    public void write(MonitorInfo<?> monitorInfo) {
        LinkInfo link = monitorInfo.getLink();
        LinkLogUtil.DigestLog digestLog = LinkLogUtil.newDigestLog(monitorInfo.getGroup(), monitorInfo.getBiz(), monitorInfo.getAction())
                .success(monitorInfo.isSuccess())
                //状态
                .status(monitorInfo.getStatus())
                //耗时
                .cost(monitorInfo.getCost())
                //性能指标
                .performance(monitorInfo.getPerformance())
                .pointLink(link);
        digestLog.setDigests(monitorInfo.getDigests());
        digestLog.setTags(monitorInfo.getTags());
        Map<String, Object> details = monitorInfo.getDetails();
        if (details == null) {
            digestLog.setAttachment(link.getShortDetails());
        } else{
            if (link.getShortDetails() != null) {
                HashMap<String, Object> attrs = new HashMap<>();
                attrs.putAll(details);
                attrs.putAll(link.getShortDetails());
                digestLog.setAttachment(attrs);
            }
        }

        digestLog.log();

//        记录链路日志
        logLink(monitorInfo, link);
    }

    /**
     * 记录链路日志
     *
     * @param monitorInfo 非空
     * @param link        非空
     */
    private void logLink(MonitorInfo<?> monitorInfo, LinkInfo link) {
        //        LinkLogUtil.newProfilerLog(link).log();
        //LinkLogUtil.newLinkLog(link).log();

        //分支节点
        if (!monitorInfo.isRoot()) {
            return;
        }

        //根节点
        int nodeNum = monitorInfo.getNodeNum();
        if (nodeNum < 2 || nodeNum > 500) {
            //太多 || 太少 没必要
            return;
        }

        //大而全的链路日志
        if (monitorInfo.isDebug()) {
            //debug场景输出json链路,也可在测试环境全输出
            LinkLogUtil.newLinkLog(link).log();
            return;
        }

        //简易链路日志,线上建议加配置实际接口判断,防止乱打
        //错(自己或子节点错/catch异常) || 慢
        if (monitorInfo.isSampling() || monitorInfo.isImplicitError() || monitorInfo.isImplicitSlow()) {
            LinkLogUtil.newProfilerLog(link).log();
        }
    }


    private static class Single {
        private static final SimpleMonitorWriter SINGLE = new SimpleMonitorWriter();
    }
}
